package com.chushouya.manager.service.admin.impl;

import com.chushouya.common.support.Contexts;
import com.chushouya.manager.dao.entity.ArticleCategoryEntity;
import com.chushouya.manager.dao.repository.ArticleCategoryRepository;
import com.chushouya.manager.dto.admin.article.*;
import com.chushouya.manager.dto.admin.article.*;
import com.chushouya.manager.service.admin.ArticleCategoryService;
import com.general.framework.core.lang.Beans;
import com.general.framework.core.lang.Lists;
import com.general.framework.core.lang.Numbers;
import com.general.framework.core.lang.Validate;
import com.general.framework.core.schema.PageResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ArticleCategoryServiceImpl implements ArticleCategoryService {

    @Resource
    private ArticleCategoryRepository articleCatRepository;

    @Override
    public void save(ArticleCatSaveDTO dto) {
        // checkParent(dto.getParentId());
        ArticleCategoryEntity entity = Beans.copy(dto, ArticleCategoryEntity.class);
        entity.setHandleUser(Contexts.getUserContext().getUserName());
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
        entity.setDelFlag(Numbers.INTEGER_ZERO);
        articleCatRepository.insertSelective(entity);
    }

    /**
     * 新增保证parentId存在即可
     */
    private void checkParent(Long parentId) {
        if (parentId != null) {
            Validate.isFalse(articleCatRepository.existsWithPrimaryKey(parentId), "父节点不存在");
        }
    }

    /**
     * 更新分类, 修改parentId的时候必须保证父节点不在当前的子节点下,否则会形成循环
     *
     * @param entity   要修改的分类
     * @param parentId 新的parentId
     */
    private void updateCheckParent(ArticleCategoryEntity entity, Long parentId) {
        if (parentId == null) {
            return;
        }
        // 找到当前entity的所有下级分类, 如果下级id和parentId一致, 报错, 一直到没有下级为止
        List<ArticleCategoryEntity> list = articleCatRepository.selectSubList(entity.getCategoryId());
        if (Lists.isEmpty(list)) {
            return;
        }
        Validate.isTrue(list.stream().anyMatch(item -> Objects.equals(item.getCategoryId(), parentId)), "父id存在嵌套循环,无法使用");
        for (ArticleCategoryEntity cat : list) {
            updateCheckParent(cat, parentId);
        }
    }

    @Override
    public List<ArticleCatListDTO> list(ArticleCategoryQuery query) {
        PageResult<ArticleCategoryEntity> pageResult = articleCatRepository.selectPage(query);
        return listToTree(pageResult.getRows(), 0L);
    }

    /**
     * 分类列表转层级结构
     *
     * @param entityList 分类列表
     * @param parentId   顶级父id, 当前为0
     */
    private List<ArticleCatListDTO> listToTree(List<ArticleCategoryEntity> entityList, Long parentId) {
        if (Lists.isEmpty(entityList)) {
            return Collections.emptyList();
        }
        List<ArticleCategoryEntity> collect = entityList.stream().filter(item -> Objects.equals(item.getParentId(), parentId)).collect(Collectors.toList());
        if (Lists.isEmpty(collect)) {
            return Collections.emptyList();
        }
        List<ArticleCatListDTO> result = Beans.copyList(collect, ArticleCatListDTO.class);
        for (ArticleCatListDTO item : result) {
            item.setSubs(listToTree(entityList, item.getCategoryId()));
        }
        return result;
    }

    @Override
    public void update(ArticleCatUpdateDTO dto) {
        ArticleCategoryEntity entity = selectByPrimaryKey(dto.getCategoryId());
        if (!Objects.equals(entity.getParentId(), dto.getParentId())) {
            updateCheckParent(entity, dto.getParentId());
        }
        ArticleCategoryEntity update = Beans.copy(dto, ArticleCategoryEntity.class);
        update.setUpdateTime(new Date());
        update.setHandleUser(Contexts.getUserContext().getUserName());
        articleCatRepository.updateByPrimaryKeySelective(update);
    }

    private ArticleCategoryEntity selectByPrimaryKey(Long id) {
        Validate.isNull(id, "分类id不存在");
        ArticleCategoryEntity entity = articleCatRepository.selectByPrimaryKey(id);
        Validate.isNull(entity, "分类id不存在");
        return entity;
    }

    @Override
    public void remove(Long id) {
        Validate.isNull(id, "id不存在");
        ArticleCategoryEntity update = new ArticleCategoryEntity();
        update.setCategoryId(id);
        update.setDelFlag(Numbers.INTEGER_ONE);
        update.setUpdateTime(new Date());
        update.setHandleUser(Contexts.getUserContext().getUserName());
        articleCatRepository.updateByPrimaryKeySelective(update);
    }

    @Override
    public ArticleCatDetailDTO detail(Long id) {
        ArticleCategoryEntity entity = selectByPrimaryKey(id);
        return Beans.copy(entity, ArticleCatDetailDTO.class);
    }

    @Override
    public void switchStatus(Long id, Integer status) {
        Validate.isNull(id, "id不能为空");
        Validate.isNull(status, "状态不能为空");
        ArticleCategoryEntity entity = selectByPrimaryKey(id);
        if (Objects.equals(entity.getStatus(), status)) {
            return;
        }
        ArticleCategoryEntity update = new ArticleCategoryEntity();
        update.setCategoryId(id);
        update.setStatus(status);
        update.setUpdateTime(new Date());
        update.setHandleUser(Contexts.getUserContext().getUserName());
        articleCatRepository.updateByPrimaryKeySelective(update);
    }

}
